﻿using System;
using System.Collections.Generic;
using AdministradorGeneral.Empresas;
using CapaDatos;
using Entidades;
using Ext.Net;
using IU.Contabilidad;
using IU.Generico.Events;
using ModuloVentas;
using WebHelper;
using Traductor;

#warning Borrar "TipoLista" de la base de datos

namespace IU.VentasCuentasCobrar.Comprobantes
{

    public partial class IngresarComprobante : System.Web.UI.Page
    {
        /* Principal */

        #region Atributos
        private const string sessionTipo = "IngreComp.Tipo";
        private const string sessionCanClick = "CanClickC";

        public object SelectedItem
        {
            get { return Session["ASelitC"]; }
            set { Session["ASelitC"] = value; }
        }

        public object SelectedId
        {
            get { return Session["ASelidC"]; }
            set { Session["ASelidC"] = value; }
        }

        public List<ItemComprobante> ItemsComprobante
        {
            get { return (List<ItemComprobante>)Session["TempLineasComprobante"]; }
            set { Session["TempLineasComprobante"] = value; }
        }

        #endregion

        #region Eventos

        /// <summary>
        /// Si no tenés permisos deniega el acceso.
        /// Si hay permisos:
        /// 1. Genera el grid de items de comprobante.
        /// 2. Carga las monedas disponibles.
        /// 3. Carga los clientes.
        /// 4. Carga las provincias.
        /// 5. Carga los tipos de operación.
        /// 6. Llena el código de facturación de sucursal con su respectivo valor.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!ContabilidadGlobal.Admin.Permisos.Alta)
            {
                Session["Mensaje"] = "Usted no tiene los permisos para acceder a esta sección.";
                Session["Titulo"] = "Acceso denegado";
                Response.Redirect("../../Mensaje.aspx");
            }
            else if (!X.IsAjaxRequest)
            {
                SelectedItem = null;

                /* Datagrid */
                Storer st = new Storer(typeof(ItemComprobante));
                st.ObjectToStore(ref StoreItems);
                st.ObjectToGridPanel(ref GridPanelItems, false);
                ItemsComprobante = new List<ItemComprobante>();
                CargarDatosEnGrid();
                CargarDatosCombos();

                NumberFieldSucursal.Value = Sucursal.ObtenerCodigoFacturacion(ContabilidadGlobal.Admin.CodEmpresa, ContabilidadGlobal.Admin.CodSucursal);

                DateFieldFecha.Value = DateTime.Today;

                /* Bugfixer [Ver ingreso de asientos]. */
                Session[sessionCanClick] = true;

                /* Valores default en parámetros */
                NumberFieldDescuento.Value = 0;
                NumberFieldIVA.Value = 21;

                /* Seleccionar pestaña 2 */
                TabPanel1.ActiveIndex = 2;
            }

            ComboClasesProductos.Tipo = typeof(Entidades.Entity_producto);
            ComboClasesProductos.Width = 300;
            ComboClasesProductos.Valores = new SqlValor[]
            {
                new SqlValor("Sucursal_codigosucursal", ContabilidadGlobal.Admin.CodSucursal),
                new SqlValor("Sucursal_empresa_idempresa", ContabilidadGlobal.Admin.CodEmpresa)
            };
            ComboClasesProductos.OnShow();

            ComboClasesServicios.Tipo = typeof(Entidades.Entity_servicio);
            ComboClasesServicios.Width = 300;
            ComboClasesServicios.Valores = new SqlValor[]
            {
                new SqlValor("Sucursal_codigosucursal", ContabilidadGlobal.Admin.CodSucursal),
                new SqlValor("Sucursal_empresa_idempresa", ContabilidadGlobal.Admin.CodEmpresa)
            };
            ComboClasesServicios.OnShow();

        }

        private void CargarDatosCombos()
        {
            StoreComboTipoOperacion.DataSource = AdministradorVentas.ObtenerListadoTiposOperacion();
            StoreComboTipoOperacion.DataBind();
            StoreComboProvincia.DataSource = AdministradorVentas.ObtenerListadoProvincias();
            StoreComboProvincia.DataBind();
            StoreComboMoneda.DataSource = AdministradorVentas.ObtenerListadoMonedas();
            StoreComboMoneda.DataBind();
            StoreComboCliente.DataSource = AdministradorVentas.ObtenerListadoClientes();
            StoreComboCliente.DataBind();
            StoreCondicionVenta.DataSource = AdministradorVentas.ObtenerCondicionVenta();
            StoreCondicionVenta.DataBind();
            StorePuntoVenta.DataSource = AdministradorVentas.ObtenerPuntosVenta();
            StorePuntoVenta.DataBind();
        }

        [DirectMethod]
        public void ComboBoxCliente_OnSelect(object sender, DirectEventArgs e)
        {
            var valor = ComboBoxCliente.Value;
            object objeto = null;
            ComboClasesCliente_AlSeleccionar(this, new EventSelectCombo(valor, objeto));
        }

        /// <summary>
        /// Al seleccionar una moneda, llenar el combo de cambio.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        [DirectMethod]
        public void ComboBoxMoneda_OnSelect(object sender, DirectEventArgs e)
        {
            var valor = ComboBoxMoneda.Value;

            var datosCliente = Gestor<Entity_cambiomoneda>.Listar(string.Format("Moneda_idmoneda={0} ORDER BY Fechacambio DESC", valor));

            object[] toStore = new object[datosCliente.Count];
            for (int i = 0; i < datosCliente.Count; i++)
            {
                toStore[i] = new object[] { 
                    datosCliente[i].Fechacambio.Ticks,
                    string.Format("{0} - {1}, {2}", datosCliente[i].Fechacambio.ToShortDateString(), datosCliente[i].Compra, datosCliente[i].Venta) };
            }

            StoreFechaCambio.DataSource = toStore;
            StoreFechaCambio.DataBind();
        }

        /// <summary>
        /// Al seleccionar un cliente, deja en el listado de facturas solo 
        /// las que este puede usar.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ComboClasesCliente_AlSeleccionar(object sender, IU.Generico.Events.EventSelectCombo e)
        {
            var datosCliente = new Entidades.Entity_cliente
            {
                Codcliente = int.Parse(e.Valor.ToString()),
                Empresa_idempresa = ContabilidadGlobal.Admin.CodEmpresa
            };
            datosCliente = Gestor<Entity_cliente>.Cargar(datosCliente);

            if (datosCliente != null)
            {
                var cliente = new Cliente(datosCliente);
                cliente.CargarDatosImpositivos();

                var tipos = cliente.ObtenerTiposFactura(ContabilidadGlobal.Admin.SituacionIva);

                object[] toStore = new object[tipos.Count];
                for (int i = 0; i < tipos.Count; i++)
                {
                    toStore[i] = new object[] { tipos[i] };
                }

                StoreComboLetra.DataSource = toStore;
                StoreComboLetra.DataBind();

                this.LetraSeleccionada(true);
            }
            else
            {
                this.LetraSeleccionada(false);
            }
        }

        #endregion

        #region DirectMethods

        [DirectMethod]
        public void LimpiarBuffer()
        {
            ItemsComprobante.Clear();
        }

        [DirectMethod(Timeout=999999)]
        public void RegistrarTodo(
            string datos, string concepto, 
            string date, int codCliente, 
            long fechaCambio, int codMoneda, 
            int idCondicionVenta, int idpuntoventa,
            string tipo, string letra, 
            int numeroSuc, int tipoOperacion, 
            int codProvincia, float descuento)
        {
            try
            {
                /* Limpia movimientos procesados previamente */
                LimpiarBuffer();

                /* Procesa los items */
                string[] lineas = datos.Split('|');
                foreach (string linea in lineas)
                {
                    string[] valor = linea.Split('\r');

                    this.ItemsComprobante.Add(new ItemComprobante
                    {
                        Codigo = int.Parse(valor[0]),
                        Descripcion = valor[1],
                        Tipo = valor[2],
                        Cantidad = int.Parse(valor[3]),
                        PrecioUnitario = TraductorHelper.Parse(valor[4])
                    });
                }

                /* Genera y guarda el comprobante, y sus servicios asociados */
                bool bienDeUso = CheckBoxBienDeUso.Checked;
                DateTime fecha = DateTime.Parse(date);
                DateTime fechaContab = DateTime.Now;

                int num = -1;
                num = AdministradorVentas.IngresarComprobanteVenta(
                    bienDeUso, codCliente, codMoneda, descuento, 
                    idCondicionVenta, fecha, new DateTime(fechaCambio), 
                    fechaContab, TiposComprobantes.FromString(tipo), letra, idpuntoventa, 
                    numeroSuc, tipoOperacion, codProvincia,
                    this.ItemsComprobante);

                if (num >= 0)
                {
                    /* Genera y guarda los asientos correspondientes */

                    /* Actualiza el campo de numero */
                    NumberFieldNumero.SetValue(num);
                    ButtonContinuar.Show();
                    ButtonCancelar.Hide();
                }
                else
                {
                    throw new Exception("Ha ocurrido un error con la base de datos. Por favor, intente registrar el comprobante más tarde.");
                }
            }
            catch (Exception ex)
            {
                ButtonAceptar.Show();
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

        [DirectMethod]
        public void BotonAceptar_Click(object sender, DirectEventArgs e)
        {
            // Botón de aceptar de ventana
        }

        [DirectMethod]
        public void BotonCerrar_Click(object sender, DirectEventArgs e)
        {
            Session["Mensaje"] = "Por favor, cierre la pestaña.";
            Session["Titulo"] = "Operación cancelada";
            Response.Redirect("../../Mensaje.aspx");
        }
		
		[DirectMethod]
        public void BotonCancelar_Click(object sender, DirectEventArgs e)
		{
            Response.Redirect("IngresarComprobante.aspx");
		}

        [DirectMethod]
        protected void OnRowSelect_Event(object sender, DirectEventArgs e)
        {
            SelectedItem = null;
            try
            {
                string json = e.ExtraParams["Values"];
                Dictionary<string, string>[] rows = JSON.Deserialize<Dictionary<string, string>[]>(json);
                Storer st = new Storer(typeof(ItemComprobante));
                SelectedId = rows[0][st.Armador.Atributos[0].Nombre];
                SelectedItem = st.MakeObjectFromRow(rows);
            }
            catch { }
        }

        [DirectMethod]
        protected void BotonAgregar_Click(object sender, DirectEventArgs e)
        {
            NumberFieldCantidad.Value = 1;
            NumberFieldCantidad.Hidden = false;
            Session[sessionTipo] = "P";
            PanelComboProductos.Hidden = false;
            PanelComboServicios.Hidden = true;
            Session[sessionCanClick] = true; /* Bugfix */
            VentanaMov.Show();
        }

        [DirectMethod]
        protected void BotonAgregarServicio_Click(object sender, DirectEventArgs e)
        {
            NumberFieldCantidad.Value = 1;
            NumberFieldCantidad.Hidden = true;
            Session[sessionTipo] = "S";
            PanelComboProductos.Hidden = true;
            PanelComboServicios.Hidden = false;
            Session[sessionCanClick] = true; /* Bugfix */
            VentanaMov.Show();
        }

        [DirectMethod]
        protected void BotonQuitar_Click(object sender, DirectEventArgs e)
        {
            try
            {
                if (SelectedItem != null)
                {
                    this.RemoveSelected();
                    this.ActualizarTotales();
                }
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

        [DirectMethod]
        protected void BotonModificar_Click(object sender, DirectEventArgs e)
        {
            Session["Modificar"] = true;
            Session[sessionCanClick] = true; /* Bugfix */
            var row = (ItemComprobante)SelectedItem;
            if (row != null)
            {
                /*TextFieldLeyenda.Text = row.Leyenda;
                TextFieldCuenta.Text = row.Cuenta;
                TextFieldMonto.Text = (float.Parse(row.Debe) == 0) ? row.Haber : row.Debe;
                ComboBoxDebeHaber.Value = (float.Parse(row.Debe) == 0) ? "H" : "D";
                TextFieldDescripcion.Text = row.Descripcion;*/
            }
            VentanaMov.Show();
        }
        #endregion

        #region Métodos

        private void QuitarItem(int cod)
        {
            int i = 0;
            while (i < ItemsComprobante.Count && cod != ItemsComprobante[i].Codigo)
            {
                i++;
            }

            if (i < ItemsComprobante.Count)
            {
                ItemsComprobante.RemoveAt(i);
            }
        }

        private void RemoveSelected()
        {
            StoreItems.RemoveRecord(SelectedId);
            var item = (ItemComprobante)SelectedItem;
            this.QuitarItem(item.Codigo);
        }

        private void ActualizarTotales()
        {
            X.AddScript("actualizarImportes();actualizarTotales();");
        }

        protected void CargarDatosEnGrid()
        {
            try
            {
                StoreItems.DataSource = ItemsComprobante;
                StoreItems.DataBind();
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

        protected void LetraSeleccionada(bool value)
        {
            if (value)
            {
                ComboBoxLetra.Show();
                ComboBoxTipo.Show();
                LabelSeleccioneCliente.Hide();
                //PanelItems.Enabled = true;
                //PanelItems.Disabled = false;
            }
            else
            {
                ComboBoxLetra.Hide();
                //PanelItems.Enabled = false;
                //PanelItems.Disabled = true;
                ComboBoxTipo.Hide();
                LabelSeleccioneCliente.Show();
            }
        }

        #endregion

        /* Ventana de items  */

        #region DirectMethods
        [DirectMethod]
        protected void Window1_BotonAceptar_Click(object sender, DirectEventArgs e)
        {
            try
            {
                if ((bool)Session[sessionCanClick])
                {
                    /* ALTA */
                    Dictionary<string, string> dict = JSON.Deserialize<Dictionary<string, string>>(e.ExtraParams["values"]);
                    string tipo = Session[sessionTipo].ToString();
                    float cant;
                    int cod;
                    string desc;
                    float precio;

                    if (tipo.Equals("S", StringComparison.OrdinalIgnoreCase))
                    {
                        cod = int.Parse(dict["ComboClasesServicios_ComboBoxObjetos_Value"]);
                        desc = dict["ComboClasesServicios_ComboBoxObjetos"];
                        precio = Servicio.ObtenerPrecio(cod, ContabilidadGlobal.Admin.CodEmpresa, ContabilidadGlobal.Admin.CodSucursal);
                        cant = 1;
                    }
                    else
                    {
                        cod = int.Parse(dict["ComboClasesProductos_ComboBoxObjetos_Value"]);
                        desc = dict["ComboClasesProductos_ComboBoxObjetos"];
                        precio = Producto.ObtenerPrecio(cod, ContabilidadGlobal.Admin.CodEmpresa, ContabilidadGlobal.Admin.CodSucursal);
                        cant = TraductorHelper.Parse(dict["NumberFieldCantidad"]);
                    }

                    ItemComprobante linea;
                    linea = new ItemComprobante
                    {
                        Cantidad = cant,
                        Tipo = tipo,
                        Codigo = cod,
                        Descripcion = desc, 
                        PrecioUnitario = precio,
                        Importe = cant*precio
                    };
                    //ItemsComprobante.Add(linea); // La quito así la uso directamente en "RegistrarTodo" + js
                    StoreItems.AddRecord(linea, true);

                    this.ActualizarTotales();
                }
            }
            catch
            { }

            Session[sessionCanClick] = false; /* Bugfix */

            this.CerrarVentana();
        }

        [DirectMethod]
        protected void Window1_BotonCancelar_Click(object sender, DirectEventArgs e)
        {
            this.CerrarVentana();
        }
        #endregion

        #region Métodos
        /// <summary>
        /// Oculta la ventana y resetea todos sus campos.
        /// </summary>
        private void CerrarVentana()
        {
            VentanaMov.Hide();
        }
        #endregion
    }
}
